<template>
  <Modal
    v-model="showOrganizeTestsuiteModal"
    :title="projectTestsuiteSetName"
    :mask-closable="false"
    :closable="false"
    fullscreen
    @on-cancel="handleOrganizeTestsuiteCancel"
  >
    <Card title="场景源" :dis-hover="true">
      <Form
        inline
        label-position="right"
        :label-width="90"
        :model="searchParams"
        slot="extra"
      >
        <FormItem label="所属项目" prop="project">
          <Select
            v-model="searchParams.project"
            filterable
            clearable
            style="width: 250px"
          >
            <Option v-for="item in projects" :value="item.id" :key="item.id">{{
              item.name
            }}</Option>
          </Select>
        </FormItem>
        <FormItem label="场景名称">
          <Input
            clearable
            placeholder="请输入场景名称"
            v-model="searchParams.name"
            style="width: 250px"
          />
        </FormItem>
        <FormItem label="场景创建人">
          <Select
            v-model="searchParams.creator"
            filterable
            multiple
            :max-tag-count="1"
            style="width: 250px"
          >
            <Option
              v-for="(item, index) in users"
              :value="item.id"
              :label="item.real_name"
              :key="index"
            ></Option>
          </Select>
        </FormItem>
        <Button
          type="primary"
          icon="ios-search"
          class="card-extra-item"
          @click="search"
          >查询</Button
        >
        <Button
          type="default"
          icon="ios-refresh"
          class="card-extra-item"
          @click="reset"
          >重置</Button
        >
        <Button
          type="text"
          :icon="showMore ? 'ios-arrow-up' : 'ios-arrow-down'"
          class="card-extra-item"
          @click="showMore = !showMore"
          >{{ showMore ? "收起" : "展开" }}</Button
        >
      </Form>
      <CollapseTransition>
        <div v-show="showMore">
          <Table
            :columns="testsuiteColumns"
            :data="testsuiteData"
            border
            size="small"
            style="margin-top: 5px"
            :max-height="500"
            :tooltip-max-width="500"
          >
            <template slot-scope="{ row }" slot="project">
              {{ row.project.name }}
            </template>
            <template slot-scope="{ row }" slot="testcase">
              <Tag
                :color="item.type === 'HTTP_API' ? 'blue' : 'green'"
                v-for="(item, index) in row.testcases"
                :key="index"
                type="border"
                >{{ item.testcase_name || item.ext_method_name }}</Tag
              >
            </template>
            <template slot-scope="{ row }" slot="level">
              <div class="levelDiv">
                <div
                  :class="
                    'levelSelect-prefix levelOption-' + row.level.toLowerCase()
                  "
                ></div>
                <div>{{ levels[row.level] }}</div>
              </div>
            </template>
            <template slot-scope="{ row }" slot="status">
              <Icon
                size="24"
                :color="statusColor[row.status]"
                type="ios-leaf"
              />
            </template>
            <template slot-scope="{ row }" slot="action">
              <Button
                size="small"
                type="text"
                style="color: #2d8cf0"
                @click="selectTestsuite(row)"
                >选择</Button
              >
            </template>
          </Table>
          <Page
            transfer
            :total="page.total"
            :current="page.current"
            :page-size="page.pageSize"
            :page-size-opts="page.pageSizeOpts"
            size="small"
            show-elevator
            show-sizer
            show-total
            prev-text="上一页"
            next-text="下一页"
            style="margin-top: 15px"
            @on-change="change"
            @on-page-size-change="pageSizeChange"
          />
        </div>
      </CollapseTransition>
    </Card>
    <Card title="组织场景 (拖动调整顺序)" :dis-hover="true">
      <Table
        :columns="selectedTestsuiteColumns"
        :data="selectedTestsuiteData"
        border
        draggable
        size="small"
        style="margin-top: 5px"
        :max-height="500"
        :tooltip-max-width="500"
        @on-drag-drop="dragDropSelectedTestsuiteData"
      >
        <template slot-scope="{ row, index }" slot="testsuite_name">
          <tooltip
            transfer
            max-width="500"
            style="width: 100%"
            placement="bottom"
            :content="selectedTestsuiteData[index].testsuite_name"
          >
            <Input
              readonly
              placeholder="请输入场景名称"
              v-model="selectedTestsuiteData[index].testsuite_name"
              style="width: 100%"
            />
          </tooltip>
        </template>
        <template slot-scope="{ row }" slot="project">
          {{ row.testsuite.project.name }}
        </template>
        <template slot-scope="{ row, index }" slot="loop_count">
          <InputNumber
            :min="1"
            :precision="0"
            style="width: 100%"
            v-model="selectedTestsuiteData[index].loop_count"
          ></InputNumber>
        </template>
        <template slot-scope="{ row }" slot="testcase">
          <Tag
            :color="item.type === 'HTTP_API' ? 'blue' : 'green'"
            v-for="(item, index) in row.testsuite.testcases"
            :key="index"
            type="border"
            >{{ item.testcase_name || item.ext_method_name }}</Tag
          >
        </template>
        <template slot-scope="{ row }" slot="remark">
          <Tooltip
            :content="row.testsuite.remark"
            max-width="500"
            transfer
            placement="bottom-start"
          >
            {{ row.testsuite.remark }}
          </Tooltip>
        </template>
        <template slot-scope="{ row, index }" slot="action">
          <i-switch
            v-model="row.is_execute"
            size="large"
            true-color="#19be6b"
            false-color="#ff4949"
            @on-change="
              selectedTestsuiteData[index]['is_execute'] = row.is_execute
            "
          >
            <span slot="open">执行</span>
            <span slot="close">跳过</span>
          </i-switch>
          <Button
            size="small"
            type="text"
            style="color: #ed4014"
            @click="removeSelectedTestsuite(row, index)"
            >移除</Button
          >
        </template>
      </Table>
    </Card>
    <div slot="footer">
      <Button type="default" @click="handleOrganizeTestsuiteCancel"
        >取消</Button
      >
      <Button type="primary" @click="handleOrganizeTestsuiteSubmit"
        >确定</Button
      >
    </div>
  </Modal>
</template>

<script>
import { getTestsuites } from "@/api/HttpAutoTestService/testsuite";
import {
  createTestsuiteSet2Testsuite,
  getTestsuiteSet2Testsuites,
} from "@/api/HttpAutoTestService/testsuite-set2testsuite";
import { getUserNames } from "@/api/HttpAutoTestService/user";
import { getProjectNames } from "@/api/HttpAutoTestService/project";
import CollapseTransition from "_c/collapse-transition/collapse-transition.js";

export default {
  name: "testsuite-set2testsuite",
  components: {
    CollapseTransition,
  },
  props: {
    organizeTestsuite: {
      type: Boolean,
      default: false,
    },
    project: {
      type: Object,
      default: () => {
        return {};
      },
    },
    testsuiteSet: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  data() {
    return {
      showMore: true,
      testsuiteExtMethodEdit: false,
      testsuiteTestcaseEdit: false,
      statusColor: {
        INITIAL: "#2db7f5",
        PASS: "#19be6b",
        PARTIAL_PASS: "#ff9900",
        FAIL: "#ed4014",
      },
      searchParams: {
        project: "",
        name: "",
        creator: [],
      },
      testsuiteColumns: [
        {
          title: "场景名称",
          key: "name",
          width: 350,
          fixed: "left",
          tooltip: true,
        },
        {
          title: "所属项目",
          slot: "project",
          width: 350,
          tooltip: true,
          align: "center",
        },
        {
          title: "测试用例",
          slot: "testcase",
          minWidth: 350,
          tooltip: true,
        },
        {
          title: "创建时间",
          key: "create_time",
          width: 160,
          align: "center",
          sortable: true,
        },
        {
          title: "更新时间",
          key: "update_time",
          width: 160,
          align: "center",
          sortable: true,
        },
        {
          title: "重要级别",
          slot: "level",
          align: "center",
          width: 85,
          fixed: "right",
        },
        {
          title: "状态",
          slot: "status",
          align: "center",
          width: 65,
          fixed: "right",
        },
        {
          title: "操作",
          slot: "action",
          align: "center",
          width: 80,
          fixed: "right",
        },
      ],
      testsuiteData: [],
      selectedTestsuiteColumns: [
        {
          title: "场景名称",
          slot: "testsuite_name",
          width: 350,
          align: "center",
          fixed: "left",
        },
        {
          title: "所属项目",
          slot: "project",
          width: 350,
          tooltip: true,
          align: "center",
        },
        {
          title: "循环次数",
          slot: "loop_count",
          width: 120,
          align: "center",
        },
        {
          title: "测试用例",
          slot: "testcase",
          minWidth: 350,
          tooltip: true,
        },
        {
          title: "操作",
          slot: "action",
          align: "center",
          width: 140,
          fixed: "right",
          renderHeader: (h, params) => {
            return h(
              "div",
              {
                style: {
                  display: "flex",
                  justifyContent: "space-between",
                  alignItems: "center",
                },
              },
              [
                h("div", "操作"),
                h(
                  "Button",
                  {
                    props: {
                      tpye: "text",
                      size: "small",
                      ghost: true,
                    },
                    style: {
                      color: "#ed4014",
                      marginLeft: "5px",
                    },
                    on: {
                      click: () => {
                        this.selectedTestsuiteData = [];
                      },
                    },
                  },
                  "清空"
                ),
              ]
            );
          },
        },
      ],
      selectedTestsuiteData: [],
      users: [],
      projects: [],
      levels: {
        LOW: "低",
        NORMAL: "中",
        HIGH: "高",
        HIGHER: "更高",
      },
      page: {
        current: 1,
        total: 0,
        pageSize: 30,
        pageSizeOpts: [10, 30, 50, 100, 200],
      },
    };
  },
  watch: {
    organizeTestsuite(val) {
      if (val) {
        this.searchParams.project = this.project.id;
        this.searchParams.creator = [this.$store.state.user.id];
        this.search();
      }
    },
    testsuiteSet(val) {
      if (this.showOrganizeTestsuiteModal && val) {
        setTimeout(() => {
          getTestsuiteSet2Testsuites({ testsuite_set: val.id })
            .then((res) => {
              this.selectedTestsuiteData = res.data;
            })
            .catch((err) => {});
        }, 1000);
      }
    },
  },
  computed: {
    showOrganizeTestsuiteModal: {
      get() {
        return this.organizeTestsuite;
      },
      set(val) {
        this.$emit("update:organizeTestsuite", val);
        this.$emit("update:project", {});
        this.$emit("update:testsuiteSet", {});
      },
    },
    projectTestsuiteSetName() {
      return `项目：${this.project.name} | 场景集：${this.testsuiteSet.name}`;
    },
  },
  mounted() {
    // 获取用户
    getUserNames()
      .then((res) => {
        this.users = res.data;
      })
      .catch((err) => {
        this.$Modal.error({
          title: "系统异常，请联系管理员……",
          content: JSON.stringify(err),
          closable: true,
        });
      });
    // 获取项目
    getProjectNames()
      .then((res) => {
        this.projects = res.data;
      })
      .catch((err) => {
        this.$Modal.error({
          title: "系统异常，请联系管理员……",
          content: JSON.stringify(err.response.data),
          closable: true,
        });
      });
  },
  methods: {
    reset() {
      this.searchParams = {
        project: "",
        name: "",
        creator: [],
      };
      this.search();
    },
    search(page) {
      let data = {
        project: this.searchParams.project,
        name: this.searchParams.name,
        creator: this.searchParams.creator.toString(),
        page: 1,
        page_size: this.page.pageSize,
      };
      if (typeof page == "number") {
        data.page = page;
      }
      this.page.current = data.page;

      getTestsuites(data)
        .then((res) => {
          const data = res.data;
          this.testsuiteData = data.results;
          this.page.total = data.count;
          if (data.next === null) {
            this.page.current = Math.ceil(this.page.total / this.page.pageSize);
          }
          if (data.previous === null) {
            this.page.current = 1;
          }
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    dragDropSelectedTestsuiteData(oldIndex, newIndex) {
      let movedRow = this.selectedTestsuiteData[oldIndex];
      this.selectedTestsuiteData.splice(oldIndex, 1);
      this.selectedTestsuiteData.splice(newIndex, 0, movedRow);
    },
    change(val) {
      this.page.current = val;
      this.search(val);
    },
    pageSizeChange(val) {
      this.page.pageSize = val;
      this.search();
    },
    selectTestsuite(row) {
      // 选择测试场景
      let selectedTestsuite = {
        testsuite_set_id: this.testsuiteSet.id,
        testsuite_set_name: this.testsuiteSet.name,
        testsuite_name: row.name,
        testsuite: {
          id: row.id,
          testcases: row.testcases,
          remark: row.remark,
          project: row.project,
        },
        is_execute: true,
        loop_count: 1,
      };
      this.selectedTestsuiteData.push(selectedTestsuite);
    },
    removeSelectedTestsuite(row, index) {
      // 移除测试场景
      this.selectedTestsuiteData.splice(index, 1);
    },
    handleOrganizeTestsuiteSubmit() {
      let testsuiteSet2testsuite = {
        testsuite_set_id: this.testsuiteSet.id,
        data: [],
      };
      if (this.selectedTestsuiteData.length > 0) {
        testsuiteSet2testsuite.data = this.selectedTestsuiteData.map(
          (item, index) => {
            if (typeof item.loop_count !== "number" || item.loop_count < 1) {
              item.loop_count = 1;
            }
            return {
              testsuite_set_id: this.testsuiteSet.id,
              testsuite_set_name: this.testsuiteSet.name,
              testsuite_id: item.testsuite.id,
              testsuite_name: item.testsuite_name,
              is_execute: item.is_execute,
              loop_count: item.loop_count,
              sort: index,
            };
          }
        );
      }
      createTestsuiteSet2Testsuite(testsuiteSet2testsuite)
        .then((res) => {
          if (res.status === 201) {
            this.$Message.info("场景组织成功");
            this.handleOrganizeTestsuiteCancel();
          } else {
            this.$Message.error("场景组织失败");
          }
        })
        .catch((err) => {
          this.$Modal.error({
            title: "系统异常，请联系管理员……",
            content: JSON.stringify(err),
            closable: true,
          });
        });
    },
    handleOrganizeTestsuiteCancel() {
      this.showOrganizeTestsuiteModal = false;
      this.selectedTestsuiteData = [];
      this.testsuiteData = [];
      this.$emit("initTestsuiteSetTable");
    },
  },
};
</script>

<style scoped>
.levelDiv {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.levelSelect-prefix {
  width: 15px;
  height: 15px;
  border-radius: 100%;
}
.levelOption-low {
  background-color: #2db7f5;
}
.levelOption-normal {
  background-color: #19be6b;
}
.levelOption-high {
  background-color: #ff9900;
}
.levelOption-higher {
  background-color: #ed4014;
}
</style>
